iT邦幫忙

2021 iThome 鐵人賽

DAY 22
0
Modern Web

在JS的世界碰碰撞撞乒乒乓乓!30天一起玩Matter.js!系列 第 22

Day22. 當蘋果掉到牛頓頭上,牛頓被敲醒了 - Gravity

  • 分享至 

  • xImage
  •  

一開始到現在,雖然我們沒有特別提到,物體就那麼自然的向下掉,就像蘋果掉到牛頓頭上的自然,這背後的理所當然,就是重力在作用。今天我們要來介紹 engine 上的 gravity 參數,我們來看看,怎麼操縱 matter.js 世界中的重力。

今日的Demo
今日的Demo原始碼
https://ithelp.ithome.com.tw/upload/images/20211007/20142057Qx67mFiTTL.png

如上段開頭引言說的,gravity 是掛在 matter.js 裡面的一個參數,所以我們可以很容易地來調整它。

它是一個物件,形式如下:

engine.gravity = {
                x: 0,
                y: 1,
                scale: 0.001
            };

基本上這三個數值就能夠操控重力的表現了。

如我們的Canvas的座標軸一樣,Y上到下是小到大,X左到右是小到大。
https://ithelp.ithome.com.tw/upload/images/20211007/20142057mhNHM4lKVR.png
預設的值是如上面展示物件結構的一樣,沒有橫向重力,y 軸重力為 1 表示向下(Canvas Y往下為正向),只有如地球一樣向下的重力,scale 是一個常數,用來同時對 x y 施加倍數增量。

我們可以稍微看一下套用重力的原始碼

/**
 * Applys a mass dependant force to all given bodies.
 * @method _bodiesApplyGravity
 * @private
 * @param {body[]} bodies
 * @param {vector} gravity
 */
Engine._bodiesApplyGravity = function(bodies, gravity) {
    var gravityScale = typeof gravity.scale !== 'undefined' ? gravity.scale : 0.001;

    if ((gravity.x === 0 && gravity.y === 0) || gravityScale === 0) {
        return;
    }
    
    for (var i = 0; i < bodies.length; i++) {
        var body = bodies[i];

        if (body.isStatic || body.isSleeping)
            continue;

        // apply gravity
        body.force.y += body.mass * gravity.y * gravityScale;
        body.force.x += body.mass * gravity.x * gravityScale;
    }
};

這邊可以看到有 matter.js 中有預寫一個函式,會是針對傳入的所有物體作重力施加判斷,但忽略 isStatic和 isSleeping 的物體。其他一般物體會被視作分別對 x y 軸施力,x y 軸施力的公式為物體本身的重量乘上 scale 增量與對應方向 x y 的重力。

使用情境也不難想像,我們可以在 engine.update 中找到呼叫的痕跡

Engine._bodiesApplyGravity(allBodies, engine.gravity);

也就是定期透過每次呼叫來對物體施加穩定、定向的力。

matter.js 實作的 engine.gravity 有一個限制,就是整個 engine 就是所有物體遵照同一個 gravity 數值,雖然一般來說重力在區塊內是單一量級很正常,但是有時候還是會有特殊需求,比如依距離或一些其他變因持續施不同方向的力。

理解後其實如果有需要,我們大可直接仿造上面的方式,自己撰寫,對物體類重力的處理方式(說到底重力其實就是力的一種、對物體施力即可表現力的存在),就如同上面的倚賴質量與軸向力。

如果要做到無重力,就是把兩個軸向的力調成 0 就可以了。

但依據上面的實作可以了解,兩軸向為0表示不對物體施力,物體本身也是不會浮起來的,只會維持在原位。

讀者可以用今天的 Demo 頁面嘗試對三個參數做調整,看一下在兩個軸向的施力上做變化物體會如何移動。
https://ithelp.ithome.com.tw/upload/images/20211007/201420574HDOKJACDQ.png
今天關於重力的介紹就到這裡,也帶讀者走過了實作原始碼,增加了一些情境下的客製想像。

可以預告一下重力會在我們最後一個專案裡扮演一個重要的角色,大家敬請期待。


上一篇
Day21. 伸縮自如的,向量圖像砲 - SVG
下一篇
Day23. 發動魔法卡,融合 - Composite (上)
系列文
在JS的世界碰碰撞撞乒乒乓乓!30天一起玩Matter.js!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言